import fs from 'fs-extra';
import path from 'path';
import { Ancestor } from './Ancestor.js';
import { ProjectType } from './BuildParams.js';
import { EngineType } from './CmdOption.js';
import { toolchain } from './toolchain.js';
import { PlatformTypes } from './typings.js';
import { Hudson } from './tools/hudson.js';

interface JobOption {
    projectName: string
    engine: EngineType
    deviceType: PlatformTypes
}

export class HudsonJob extends Ancestor {
    private jobOpt!: JobOption;

    public async awake(): Promise<boolean> {
        const [projectName, engine, deviceType] = this.cmdOption.taskParameter!.split(',');
        this.jobOpt = { projectName, engine: engine as EngineType, deviceType: deviceType as PlatformTypes };
        this.cmdOption.platform = this.jobOpt.deviceType;
        return true;
    }

    public async start(): Promise<void> {
        this.cmdOption.projectName = `${this.jobOpt.projectName}-develop`;
        await this.getParams();
        await this.makeBuildJob(this.jobOpt.projectName, this.jobOpt.engine, this.jobOpt.deviceType, 'develop');

        this.cmdOption.projectName = `${this.jobOpt.projectName}-publish`;
        await this.getParams();
        await this.makeBuildJob(this.jobOpt.projectName, this.jobOpt.engine, this.jobOpt.deviceType, 'publish');

        await this.makeBranch(this.jobOpt.projectName);
    }

    private async makeBranch(projectName: string): Promise<void> {
        const template = await this.readTemplate('make_branch.xml');
        if (template == null) return;
        const content = template.replaceAll('${ProjectName}', projectName);
        await this.writeJob(content, `${projectName}-拉分支/config.xml`);
    }

    private async makeBuildJob(projectName: string, engine: EngineType, deviceType: PlatformTypes, publishType: ProjectType): Promise<void> {
        const template = await this.readTemplate(`${engine}_${deviceType}_${publishType}.xml`);
        if (template == null) return;
        const content = template.replaceAll('${ProjectName}', projectName).replaceAll('${BuildType}', publishType).replaceAll('${packageLocalWebPath}', path.basename(toolchain.params.packageLocalWebPath));
        await this.writeJob(content, `${projectName}-${publishType}/config.xml`);
    }

    private async readTemplate(fileName: string): Promise<string | null> {
        const f = path.join(this.cmdOption.oldToolsRoot, `hudsonJobs/templates/${fileName}`);
        if (!fs.existsSync(f)) {
            console.error('template file not found:', f);
            return null;
        }
        return fs.readFile(f, 'utf-8');
    }

    private async writeJob(content: string, fileName: string): Promise<void> {
        const f = path.join(Hudson.getHudsonHome(), `jobs/${fileName}`);
        if (fs.existsSync(f)) {
            console.error('job already exists:', f);
            return;
        }
        await fs.ensureDir(path.dirname(f));
        await fs.writeFile(f, content.replaceAll('${creationTime}', String((new Date()).getMilliseconds())), 'utf-8');
    }
}